/** Promise方式 */
function sendRequest(urls, max, callback) {
    /** 并发数 */
    let pending_count = 0;
    /** 当前请求位置 */
    let idx = 0;
    
    while(pending_count < max) 
        _fetch(urls[idx++])

    async function _fetch(url) {
        if(!url) return;
        pending_count++;
        console.log(url + '：start', '并发数：' + pending_count);
        await fetch(url);
        pending_count--;
        console.log(url + '：done', '并发数：' + pending_count);
        _fetch(urls[idx++]);
        pending_count || callback && callback();
    }
}

/** 测试 */
let urls = Array.from({length: 10},(_,index)=> index);

let fetch = function(idx){
    return new Promise((resolve)=>{
        let timeout = parseInt(Math.random() * 1e4);
        setTimeout(() => {
            resolve(idx);
        }, timeout)
    })
}

let max = 4;

let callback = () => {
    console.log('run callback');
}

sendRequest(urls, max, callback);
